home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 39.4 KB | 1,353 lines | [TEXT/MPS ] |
- // UVUAssist.cp
- // Copyright © 1991-96 by Apple Computer, Inc., all rights reserved.
-
- // Contains: VU assistance methods
- // Version: 2.0d1 - MacApp 3.1 compatible version
-
- /*
- Historical Note: References to the "Mole" are equivalent to references to "Agent VU".
- "Agent VU" was previously called the "Mole".
-
- The mole sees MacApp windows as plain windows that are empty. MacApp
- doesn't put its controls in the control list, so V.U. won't even see standard
- Control Manager controls. The assistance proc updates the mole buffer before
- it is sent back to the V.U. host, telling it that there are items in the windows,
- and telling it about each item. We tell it that the windows are dialogs,
- because V.U. looks for a wider range of user interface items in dialogs.
-
- V.U. has its own hierarchy of user interface items, based largely on the types of
- interface items defined in Inside Mac which V.U. can obtain information about
- in non-MacApp applications. MacApp's user interface element hierarchy is the view hierarchy.
- Since the two hierarchies are not the same, VUAssist must perform a mapping between the
- two hierarchies. Many of these mappings are straight-forward, but a few require some
- explanation. The V.U. interface item hierarchy is as follows.
-
- |___ staticText
- |
- |___ editText
- |
- |___ picture
- contentItem-----|
- |___ icon
- |
- |___ userItem
- |
- |___ control-----|___ button
- |
- |___ checkBox
- |
- |___ radioButton
- |
- |___ scrollBar
- |
- |___ popup
-
- All V.U. interface items are considered contentItems. Some of these contentItems are
- typically found only in Dialog Manager dialogs in non-MacApp applications. These would
- be staticText, editText, picture, icon, and userItem. Controls are Control Manager controls
- which may appear in any window.
-
- The list of TView descendants which are mapped to V.U. interface items and the V.U. item
- to which they are mapped by V.U. by way of VUAssist is shown below.
-
- TStaticText ---------> staticText
- TEditText ---------> editText
- TPicture ---------> picture
- TIcon ---------> icon
- TButton ---------> button
- TCheckbox ---------> checkBox
- TRadio ---------> radioButton
- TScrollBar ---------> scrollBar
- TPopup ---------> popup
- TTextEdit ---------> editText
- (cells of TGridView -> contentItem) - an optional feature
-
- The last item, "cells of TGridView", deserves some explanation. TGridViews are a
- problem because unlike all the other items mentioned above, where there is exactly one
- MacApp object for each user interface item, there are many user interface items for a
- single TGridView object. V.U. does not yet directly support gridView types of objects.
- So there is special case code for TGridViews. Each cell in a grid is passed back as a
- "CUSTOM_ITEM". To V.U., a CUSTOM_ITEM is a user interface item which does not fall into
- any category more specific than contentItem. So from a V.U. script writer's perspective,
- cells in TGridView objects are V.U. contentItems.
-
- Note that the mapping of TGridView cells to contentItems is a feature which can be disabled.
- TVUAssist's IVUAssist method takes a Boolean argument gridItemSupport. By passing 'false'
- to this method, the cells of TGridViews are invisible to V.U.. You may want to do this if
- your application has large gridviews or many gridviews. In this case treating each cell as
- an interface item may bog down V.U. in such a way that performance is not acceptable.
-
- You'll also note in the code that we include TPopup descriptions in response to V.U.'s requests
- for information about controls. This is because V.U. can normally only support popups which
- are implemented through the use of the popup CDEF found in System 7.0 or in the Mac Communications
- Toolbox. So V.U. expects them to be controls. */
-
- /*========================================== TVUAssist ================================*/
-
- #if qNeedsVU
-
- /* ----------------- VUAssist includes -------------------- */
-
- #ifndef __UVUASSIST__
- #include "UVUAssist.h"
- #endif
-
- // MacApp
-
- #ifndef __UAPPLICATION__
- #include "UApplication.h"
- #endif
-
- #ifndef __UDIALOG__
- #include "UDialog.h"
- #endif
-
- #ifndef __UGRIDVIEW__
- #include "UGridView.h"
- #endif
-
- #ifndef __UPOPUP__
- #include "UPopup.h"
- #endif
-
- #ifndef __UWINDOW__
- #include "UWindow.h"
- #endif
-
- // Toolbox
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- /* ----------------- VUAssist typedefs -------------------- */
-
- typedef TCtlMgr *TCtlMgrPtr;
- typedef TControl *TControlPtr;
- typedef TStaticText *TStaticTextPtr;
- typedef TEditText *TEditTextPtr;
- typedef TGridView *TGridViewPtr;
- typedef TTEView *TTEViewPtr;
- typedef TGridView *TGridViewPtr;
- typedef TPopup *TPopupPtr;
- typedef TTextGridView *TTextGridViewPtr;
- typedef TGridItem *TGridItemPtr;
-
- //========================================================================================
- // GLOBAL
- //========================================================================================
-
- static long MAMoleHook(long select, Ptr input, Ptr output, short *outputSize, long result);
-
-
- /* ----------------- VUAssist global -------------------- */
-
- TVUAssist *gVUAssist;
- MoleHookUPP gMoleHookUPP = NewMoleHookProc(MAMoleHook);
-
- /* ----------------- VUAssist macros -------------------- */
-
- // pascal string length macro
- ////#define VUPstrLength(str) (short)(*(char *)str)
-
- inline short VUPLstrlen(void* s) { return (short)(*(unsigned char *)s); }
-
- //========================================================================================
- // CLASS TVUAssist
- //========================================================================================
- #undef Inherited
- #define Inherited TEventHandler
-
- #pragma segment AInit
- MA_DEFINE_CLASS_M1(TVUAssist, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TVUAssist destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TVUAssist::~TVUAssist()
- {
- }
-
- #pragma segment AVUAssist
- /* MAMoleHook accepts the call from the mole with a C interface, and then calls
- TVUAssist::MoleAssist. */
-
- long MAMoleHook(long select, Ptr input, Ptr output, short *outputSize, long result)
- {
- #if !qPowerPC
- long oldA5 = SetCurrentA5();
- #endif
- MoleError aMoleError = gVUAssist->MoleAssist(select, input, output, outputSize, result);
- #if !qPowerPC
- SetA5(oldA5);
- #endif
- return aMoleError;
- }
-
- /* IVUAssist initializes fMoleRefNum. fMoleRefNum contains the reference number of the
- mole driver, or 0 if no mole driver has been found yet. Also initializes VUAssist as an EventHandler
- and initializes fGridItemSupport according to input argument gridItemSupport.*/
-
- void TVUAssist::IVUAssist(Boolean gridItemSupport)
- {
- Inherited::IEventHandler(NULL);
- fGridItemSupport = gridItemSupport;
- fMoleRefNum = 0;
- this->OpenMoleDriver();
- }
-
-
- /* Try to open the mole driver if there is one. */
-
- void TVUAssist::OpenMoleDriver()
- {
- ParamBlockRec aPBRec;
- short Err;
-
- aPBRec.ioParam.ioCompletion = NULL;
- aPBRec.ioParam.ioNamePtr = (StringPtr)StripAddress("\p.Mole");
- aPBRec.ioParam.ioPermssn = fsCurPerm;
- Err = PBOpenSync(&aPBRec);
- if (Err == noErr) {
- fMoleRefNum = aPBRec.ioParam.ioRefNum;
- this->ResumeMole();
- }
- }
-
- /* Call this routine when the application is suspended by Multifinder, to let
- the mole know we are no longer the frontmost app. */
-
- void TVUAssist::SuspendMole()
- {
- this->SetDebuggerHook(NULL);
- }
-
-
- /* Call this routine when MultiFinder puts us back into the foreground. */
-
- void TVUAssist::ResumeMole()
- {
- this->SetDebuggerHook(gMoleHookUPP);
- }
-
-
- /* This is the routine called by MAMoleHook. It dispatches out to the routines
- which actually assist the mole. */
-
- MoleError TVUAssist::MoleAssist (long select, Ptr input, Ptr output, short *outputSize, long intResult)
- {
- MoleError ret = MoleError(intResult);
- MoleError result = MoleError(intResult);
-
- switch (select) {
-
- case SMenuInfo:
- ret = this->DoMenuInfo (input, output, outputSize, result);
- break;
-
- case SMenuItems:
- ret = this->DoMenuItems (input, output, outputSize, result);
- break;
-
- case SWindInfo:
- ret = this->DoSendWindowInfo (input, output, outputSize, result);
- break;
-
- case SFindCtl:
- ret = this->DoFindControl (input, output, outputSize, result);
- break;
-
- case SCtlInfo:
- ret = this->DoSendControlInfo (input, output, outputSize, result);
- break;
-
- case SDItemInfo:
- ret = this->DoSendDlogItemInfo (input, output, outputSize, result);
- break;
-
- case SetMItemKey:
- case SFrontWind:
- case SFindWind:
- case SFindDItem:
- default:
- break;
- }
- return ret;
- }
-
-
- #define SET_ASSIST 100
-
- /* Tell the mole the address of our assistance procedure.*/
-
- void TVUAssist::SetDebuggerHook (MoleHookUPP theNewHook)
- {
- if (fMoleRefNum)
- {
- ParamBlockRec aPBRec;
-
- aPBRec.cntrlParam.ioCompletion = NULL;
- aPBRec.cntrlParam.ioVRefNum = 0;
- aPBRec.ioParam.ioRefNum = fMoleRefNum;
- aPBRec.cntrlParam.csCode = SET_ASSIST;
- *((long *)&(aPBRec.cntrlParam.csParam[0])) = (long)theNewHook;
- ::PBControlAsync(&aPBRec);
- #if qDebug
- if (aPBRec.cntrlParam.ioResult)
- {
- ProgramBreak("Error sending Agent VU control call");
- }
- #endif
- }
- }
-
-
-
- /* ------------------------------------------------------------------------------------ */
- /* the routines for handling individual mole requests. Each routine handles
- exactly one mole request. */
-
- /*
- | Handle a request for specific menu items. The Mole can get info on menus in the
- | menu bar, but we have to supply info on popup menus. If the Input data specifies
- | a non-zero menu ID, use the ID to determine the popup menu. Otherwise, if the
- | the menu rank input parameter is 0 (unspecified) use the menu handle input parameter
- | directly to identify the popup menu. We do not deal with menus specified by non-zero
- | rank parameter (where the menu ID parameter is 0.
- */
- MoleError TVUAssist::DoMenuItems (Ptr input, Ptr output, short *outputSize, MoleError result)
- {
- SendMenuItemsParamsPtr menuReqPtr;
- MoleDataBlockPtr menuDescPtr;
- TPopup *popup;
- MenuRef theMenuRef;
-
- if (result != mNoErr) /* only do the work if agent needs help */
- {
- menuReqPtr = SendMenuItemsParamsPtr(input);
- menuDescPtr = MoleDataBlockPtr(output);
- theMenuRef = NULL;
-
- if (menuReqPtr->menu_ID != 0)
- {
- popup = this->MenuIDToPopup(menuReqPtr->menu_ID);
- if (popup != NULL)
- {
- theMenuRef = popup->GetMenuRef();
- }
- }
- else if (menuReqPtr->menu_rank == 0)
- {
- if (menuReqPtr->menu_hdl != NULL)
- {
- theMenuRef = menuReqPtr->menu_hdl;
- }
- }
- if (theMenuRef != NULL)
- {
- result = this->FillPopupItemDesc(theMenuRef, menuReqPtr->start_item,
- menuReqPtr->stop_item, menuDescPtr, outputSize);
- }
- }
- return result;
- }
-
-
- /*
- | Handle a request for menu info. The Mole can get info on menus in the
- | menu bar, but we have to supply info on popup menus. If the Input data specifies
- | a non-zero menu ID, use the ID to determine the popup menu. Otherwise, if the
- | the menu rank input parameter is 0 (unspecified) use the menu handle input parameter
- | directly to identify the popup menu. We do not deal with menus specified by non-zero
- | rank parameter (where the menu ID parameter is 0.
- */
- MoleError TVUAssist::DoMenuInfo (Ptr input, Ptr output, short *outputSize, MoleError result)
- {
- SendMenuInfoParamsPtr menuReqPtr;
- MoleMenuInfoPtr menuDescPtr;
- TPopup *popup;
- MenuRef theMenuRef;
-
- if (result != mNoErr) /* only do the work if agent needs help */
- {
- menuReqPtr = SendMenuInfoParamsPtr(input);
- menuDescPtr = MoleMenuInfoPtr(output);
- theMenuRef = NULL;
-
- if (menuReqPtr->menu_ID != 0)
- {
- popup = this->MenuIDToPopup(menuReqPtr->menu_ID);
- if (popup != NULL)
- {
- theMenuRef = popup->GetMenuRef();
- }
- }
- else if (menuReqPtr->menu_rank == 0)
- {
- if (menuReqPtr->menu_hdl != NULL)
- {
- theMenuRef = menuReqPtr->menu_hdl;
- }
- }
- if (theMenuRef != NULL)
- {
- this->FillPopupDesc(theMenuRef, RANK_OF_THE_INVISIBLE, menuDescPtr, outputSize);
- result = mNoErr;
- }
- }
- return result;
- }
-
-
- /* Revise the values of the controlCount and numItems fields of the MoleWDescPtr, given
- knowledge of MacApp views. Also update validFlags and windowKind fields. WindowKind is set
- to dialogKind so that V.U. will look for things that it can normally only see in dialogs
- (such as icons and pictures) */
-
- MoleError TVUAssist::DoSendWindowInfo (Ptr input, Ptr output, short *, MoleError result)
- {
- DWindReqPtr windReqPtr;
- MoleWDescPtr windDescPtr;
- TWindow *window;
-
- windReqPtr = DWindReqPtr(input);
- windDescPtr = MoleWDescPtr(output);
- window = this->RankToWindow (*windReqPtr);
- if (window) {
- windDescPtr->validFlags |= (VCTLCNT_MASK | VITEMCNT_MASK);
- windDescPtr->windowKind = dialogKind;
- windDescPtr->controlCount = this->ViewCount (window, FALSE);
- windDescPtr->numItems = this->ViewCount (window, TRUE);
- /* outputSize is filled in by the mole */
- return mNoErr;
- }
-
- return result;
- }
-
-
- /* The mole sends us a point location in global coordinates. We need to figure out
- which window and which control that point is in (if any), and send back info about
- that control. V.U. utilizes this routine for theControl Manager controls (TCtlMgr) only.*/
-
- MoleError TVUAssist::DoFindControl (Ptr input, Ptr output, short *outputSize, MoleError result)
- {
- SendFindControlParamPtr ctrlReqPtr;
- MoleCDescPtr ctrlDescPtr;
- SendFindControlParam targetPoint;
- short part;
- WindowRef wind;
- WindowRef windowPtr;
- GrafPtr savePort;
- TCtlMgr *theControl;
- short rank;
- ControlRef saveCtlList;
- ControlRef WhichCtl;
- TWindow *window;
- VPoint VPt;
-
- ctrlReqPtr = SendFindControlParamPtr(input);
- targetPoint = *ctrlReqPtr;
- ctrlDescPtr = MoleCDescPtr(output);
-
- part = ::FindWindow(targetPoint, &windowPtr);
- wind = windowPtr;
-
- /* The mole also tests for part=inSysWindow, but we'll let the mole handle those cases */
- if (wind && (part == inContent)) {
- window = gApplication->WMgrToWindow(WindowRef(wind));
- if (window) {
- theControl = this->PointToControl (window, targetPoint, &rank);
- if (theControl) {
- part = -1;
- /* Get the control part code. Controls are not kept in the controllist,
- so we temporarily put them in there. Also, they are in their subviews
- local coordinate system, so we must convert targetpoint. */
- ::GetPort (&savePort);
- ::SetPort (WindowRef(wind));
- if (window->Focus()) {
- saveCtlList = ((WindowPeek) wind)->controlList;
- ((WindowPeek) wind)->controlList = theControl->fCMgrControl;
- this->GlobalToWindow (window, targetPoint, &VPt);
- this->WindowToView (theControl, &VPt, &targetPoint);
- part = FindControl (targetPoint, WindowRef(wind), &WhichCtl);
- ((WindowPeek) wind)->controlList = saveCtlList;
- }
- ::SetPort (savePort);
-
- if (this->FillCtrlDesc (ctrlDescPtr, part, this->WindowToRank(wind), rank, theControl, outputSize)) {
- return mNoErr;
- }
- }
- }
- }
-
- return result;
- }
-
-
- /* Read the input parameter to see which control V.U. wants info on, then
- fill in the SendCtlInfoParamsPtr record. The mole can't gather any info about
- MacApp controls without our help, so we fill in the whole record, except for part,
- which doesn't apply.*/
-
- MoleError TVUAssist::DoSendControlInfo (Ptr input, Ptr output, short *outputSize, MoleError result)
- {
- SendCtlInfoParamsPtr ctrlReqPtr;
- MoleCDescPtr ctrlDescPtr;
- TWindow *window;
- TControl *theControl;
- TGridItem *gridItem;
-
- gridItem = NULL;
- ctrlReqPtr = SendCtlInfoParamsPtr(input);
- ctrlDescPtr = MoleCDescPtr(output);
-
- window = this->RankToWindow (ctrlReqPtr->window_rank);
- if (window) {
- theControl = TControlPtr(this->RankToItem(window, ctrlReqPtr->control_rank, FALSE, gridItem));
- if (theControl) {
- if (this->FillCtrlDesc(ctrlDescPtr, -1, ctrlReqPtr->window_rank, ctrlReqPtr->control_rank,
- theControl, outputSize))
- {
- return mNoErr;
- }
- }
- }
-
- return result;
- }
-
-
- /* Read the input to see which dialog item in which window V.U. wants data on, and
- fill in the dialogiteminfo record. */
- MoleError TVUAssist::DoSendDlogItemInfo (Ptr input, Ptr output, short *outputSize, MoleError result)
- {
- SendDItemInfoPtr dlogReqPtr;
- MoleDItemInfoPtr dlogDescPtr;
- TWindow *window;
- TView *view;
- TGridItem *gridItem;
-
- gridItem = NULL;
- dlogReqPtr = SendDItemInfoPtr(input);
- dlogDescPtr = MoleDItemInfoPtr(output);
-
- window = this->RankToWindow (dlogReqPtr->window_rank);
- if (window) {
- view = this->RankToItem (window, dlogReqPtr->item_num, TRUE, gridItem);
- if (view) {
- this->FillDlogItemDesc(dlogDescPtr, window, dlogReqPtr->window_rank, dlogReqPtr->item_num,
- view, outputSize, gridItem);
- return mNoErr;
- }
- }
-
- return result;
- }
-
-
- #pragma segment AVUAssist2
-
- /* ------------------------------------------------------------------------------------ */
- /* routines for filling in mole data structures */
-
- /* Given a TPopup object, fill in the mole's menu descriptor record. */
-
- void TVUAssist::FillPopupDesc (MenuRef theMenuHdl, short menuRank, MoleMenuInfoPtr menuDescPtr, short *outputSize)
- {
- menuDescPtr->num_items = ::CountMItems(theMenuHdl);
- menuDescPtr->rank = menuRank;
- menuDescPtr->left_edge = 0;
- menuDescPtr->menuID = (**theMenuHdl).menuID;
- menuDescPtr->menuWidth = (**theMenuHdl).menuWidth;
- menuDescPtr->menuHeight = (**theMenuHdl).menuHeight;
- menuDescPtr->enableFlags = (**theMenuHdl).enableFlags;
- MABlockMove((**theMenuHdl).menuData, menuDescPtr->menuTitle.text, VUPLstrlen((**theMenuHdl).menuData)+1);
-
- /* this ugly thing computes the length (bytes used) of MoleMenuInfo */
- *outputSize = sizeof(MoleMenuInfo) - (255 - VUPLstrlen((**theMenuHdl).menuData));
- }
-
-
- /* this function depends upon Ptr being a pointer to a single byte */
-
- static Ptr SeekMenuItem (short ItemNum, MenuRef MenuHdl)
- {
- Ptr seekPtr = Ptr(&((**MenuHdl).menuData) + VUPLstrlen((**MenuHdl).menuData) + 1);
- short seekNum = 1;
-
- while ((seekNum < ItemNum) && *seekPtr) {
- seekPtr += *seekPtr + ADDITIONAL_MENU_ITEM_DATA;
- seekNum++;
- }
-
- return seekPtr;
- }
-
-
- /* Given a TPopup object and a menu handle, fill in the mole's menuitem descriptor record. */
- MoleError TVUAssist::FillPopupItemDesc (MenuRef theMenuHdl, short start, short stop,
- MoleDataBlockPtr menuItemDescPtr, short *outputSize)
- {
- Ptr startPtr;
- Ptr stopPtr;
- MoleError ret = mNoErr;
-
- if ((start > ::CountMItems(theMenuHdl)) || (start < 1))
- {
- return mBadMenuItemIndex;
- }
-
- if (stop > ::CountMItems(theMenuHdl))
- {
- stop = ::CountMItems(theMenuHdl);
- ret = mBadLastMenuItemIndex;
- }
-
- startPtr = SeekMenuItem(start, theMenuHdl);
- stopPtr = SeekMenuItem(stop+1, theMenuHdl);
- if (! (startPtr && stopPtr))
- {
- return mBadMenuItemIndex;
- }
-
- menuItemDescPtr->blockLength = stop - start + 1;
- MABlockMove(startPtr, &menuItemDescPtr->dataBlock[0], stopPtr - startPtr);
-
- /* this ugly thing computes the length (bytes used) of MoleDataBlock */
- *outputSize = sizeof(short) + (stopPtr - startPtr);
-
- return ret;
- }
-
-
- /* Fill in a mole control descriptor record. Valid descendants of TControl are descendants of
- TCtlMgr and TPopup. Will return false if TControl is not a descendant of TCtlMgr or TPopup.*/
-
- Boolean TVUAssist::FillCtrlDesc (MoleCDescPtr ctrlDescPtr, short thePart,
- short windowRank, short ControlRank,
- TControl *theControl, short *outputSize)
- {
- ControlRef ControlHdl;
- VRect aVRect;
- CRect aCRect;
- MenuRef theMenuHdl;
- unsigned char *theExtraDataPtr;
- Boolean itsOdd;
- short outputSizeAdjustor;
- short titleLength;
-
- if (MA_MEMBER(theControl, TPopup)) {
-
- theMenuHdl = TPopupPtr(theControl)->GetMenuRef();
-
- ctrlDescPtr->validFlags = VALL_C_MASK;
- if (thePart == -1) /* indicate that part code is not valid */
- {
- ctrlDescPtr->validFlags = ctrlDescPtr->validFlags & ~VCPART_MASK;
- }
-
- ctrlDescPtr->owner_rank = windowRank;
- theControl->GetExtent (aVRect);
- VRectToRect(aVRect, aCRect);
- SetRect(&ctrlDescPtr->ctlRect, aCRect.left, aCRect.top, aCRect.right, aCRect.bottom);
- this->ViewRectToWindowRect (&ctrlDescPtr->ctlRect, theControl);
-
- ctrlDescPtr->ctlValue = TPopupPtr(theControl)->GetCurrentItem();
- ctrlDescPtr->ctlMin = 1;
- ctrlDescPtr->ctlMax = ::CountMItems(theMenuHdl);
- ctrlDescPtr->ctlHilite = 0;
- if (thePart == -1)
- {
- ctrlDescPtr->part = 0;
- }
- else
- {
- ctrlDescPtr->part = thePart;
- }
- ctrlDescPtr->ctlRank = ControlRank;
- ctrlDescPtr->ctlDefID = POPUP_CDEF * 16;
- ctrlDescPtr->ctlData.popupMenuID = TPopupPtr(theControl)->GetMenuID();
- titleLength = VUPLstrlen((**theMenuHdl).menuData);
- MABlockMove((**theMenuHdl).menuData, ctrlDescPtr->ctlTitle.text, titleLength+1);
-
- /*
- | For 7.1, we need to add the menu handle at the first even byte boundary beyond
- | end of the text_name field. This determines the location for the
- | menu handle.
- */
- theExtraDataPtr = ctrlDescPtr->ctlTitle.text + titleLength + 2;
- if (odd(theExtraDataPtr))
- {
- itsOdd = TRUE;
- theExtraDataPtr = theExtraDataPtr - 1;
- }
- else
- {
- itsOdd = FALSE;
- }
-
- /* Tack the menu handle on the end of the CtrlDescPtr */
- MABlockMove(&theMenuHdl, theExtraDataPtr, sizeof(MenuRef));
-
- /* compute the length (bytes used) of CtrlDescPtr */
- if (itsOdd)
- {
- outputSizeAdjustor = 1;
- }
- else
- {
- outputSizeAdjustor = 2;
- }
-
- /* this ugly thing computes the length (bytes used) of ctrlDescPtr */
- *outputSize = sizeof(MoleControlDescriptor) - (255-titleLength) + outputSizeAdjustor;
- return TRUE;
- }
- else
- {
- if (MA_MEMBER(theControl, TCtlMgr)) {
-
- ControlHdl = TCtlMgrPtr(theControl)->fCMgrControl;
- ctrlDescPtr->validFlags = VALL_C_MASK;
- if (thePart == -1) /* indicate that part code is not valid */
- {
- ctrlDescPtr->validFlags = ctrlDescPtr->validFlags & ~VCPART_MASK;
- }
- ctrlDescPtr->owner_rank = windowRank;
- ctrlDescPtr->ctlRect = (**ControlHdl).contrlRect;
- this->ViewRectToWindowRect (&ctrlDescPtr->ctlRect, theControl);
- ctrlDescPtr->ctlValue = (**ControlHdl).contrlValue;
- ctrlDescPtr->ctlMin = (**ControlHdl).contrlMin;
- ctrlDescPtr->ctlMax = (**ControlHdl).contrlMax;
- ctrlDescPtr->ctlHilite = (**ControlHdl).contrlHilite;
- if (thePart == -1) {
- ctrlDescPtr->part = 0;
- } else {
- ctrlDescPtr->part = thePart;
- }
- ctrlDescPtr->ctlRank = ControlRank;
-
- /* Special case TScrollBar to have ctlDefID of 16 so VU views it as a standard scroll bar */
- if (MA_MEMBER(theControl, TScrollBar))
- {
- ctrlDescPtr->ctlDefID = 16;
- }
- else
- {
- ctrlDescPtr->ctlDefID = ::GetControlVariant(ControlHdl);
- }
-
- ctrlDescPtr->ctlData.popupMenuID = 0;
- MABlockMove((**ControlHdl).contrlTitle, ctrlDescPtr->ctlTitle.text, VUPLstrlen((**ControlHdl).contrlTitle)+1);
-
- /* this ugly thing computes the length (bytes used) of ctrlDescPtr */
- *outputSize = sizeof(MoleControlDescriptor) - (255 - VUPLstrlen((**ControlHdl).contrlTitle));
-
- return TRUE;
- }
- }
- return FALSE;
- }
-
-
- void TVUAssist::ViewRectToWindowRect (Rect *aRect, TView *aView)
- {
- VPoint tl(aRect->left, aRect->top);
- aView->LocalToWindow(tl);
-
- VPoint br(aRect->right, aRect->bottom);
- aView->LocalToWindow(br);
-
- ::SetRect(aRect, (short)tl.h, (short)tl.v, (short)br.h, (short)br.v);
- }
-
- /* Fill in a mole dialog item descriptor record */
-
- void TVUAssist::FillDlogItemDesc (MoleDItemInfoPtr dlogDescPtr, TWindow *window,
- short windowRank, short itemRank, TView *item,
- short *outputSize, TGridItem *gridItem)
- {
- VRect aVRect;
- CRect aCRect;
- long textLen;
- Handle textHdl;
- ViewItems itemKind;
- GridCell aCell;
- CStr255 theText;
-
- itemKind = this->GetItemType (item, TRUE, TRUE);
-
- /* fill in box, itemType, item_enabled, has_text and text_name here */
- switch (itemKind) {
-
- case VINotMember:
- break;
-
- case VIButton:
- dlogDescPtr->itemType = btnCtrlItem;
- dlogDescPtr->item_enabled = ((TCtlMgrPtr)(item))->IsCMgrVisible() && item->IsActive();
- dlogDescPtr->has_text = TRUE;
- ((TCtlMgrPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VIRadio:
- ((TCtlMgrPtr)(item))->ControlArea (aVRect);
- dlogDescPtr->itemType = radCtrlItem;
- dlogDescPtr->item_enabled = ((TCtlMgrPtr)(item))->IsCMgrVisible() && item->IsActive();
- dlogDescPtr->has_text = TRUE;
- ((TCtlMgrPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VICheckBox:
- ((TCtlMgrPtr)(item))->ControlArea (aVRect);
- dlogDescPtr->itemType = chkCtrlItem;
- dlogDescPtr->item_enabled = ((TCtlMgrPtr)(item))->IsCMgrVisible() && item->IsActive();
- dlogDescPtr->has_text = TRUE;
- ((TCtlMgrPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VIScrollBar:
- ((TCtlMgrPtr)(item))->ControlArea (aVRect);
- dlogDescPtr->itemType = resCtrlItem;
- dlogDescPtr->item_enabled = ((TCtlMgrPtr)(item))->IsCMgrVisible() && item->IsActive();
- dlogDescPtr->has_text = TRUE;
- ((TCtlMgrPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VIStatText:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = statText;
- dlogDescPtr->item_enabled = FALSE;
- dlogDescPtr->has_text = TRUE;
- ((TStaticTextPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VIEditText:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = editText;
- dlogDescPtr->item_enabled = item->IsActive();
- dlogDescPtr->has_text = TRUE;
- ((TEditTextPtr)(item))->GetText(theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- break;
-
- case VIIcon:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = iconItem;
- dlogDescPtr->item_enabled = item->IsActive();
- dlogDescPtr->has_text = FALSE;
- dlogDescPtr->itemData.item_text_ptr = NULL;
- break;
-
- case VIPopup:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = resCtrlItem;
- dlogDescPtr->item_enabled = item->IsActive();
- dlogDescPtr->has_text = FALSE;
- dlogDescPtr->itemData.item_text_ptr = NULL;
- break;
-
- case VIPicture:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = picItem;
- dlogDescPtr->item_enabled = item->IsActive();
- dlogDescPtr->has_text = FALSE;
- dlogDescPtr->itemData.item_text_ptr = NULL;
- break;
-
- case VITextEdit:
- aVRect = item->GetExtent();
- dlogDescPtr->itemType = editText;
- dlogDescPtr->item_enabled = item->IsActive();
- dlogDescPtr->has_text = TRUE;
- textHdl = TTEViewPtr(item)->ExtractText();
- textLen = ::GetHandleSize(textHdl);
- if (textLen > 255)
- textLen = 255;
- MABlockMove(*textHdl, dlogDescPtr->itemData.text, textLen);
- break;
-
- case VIGridItem:
- gridItem->GetExtent(aVRect);
- dlogDescPtr->itemType = CUSTOM_ITEM;
- dlogDescPtr->item_enabled = gridItem->fGridView->IsActive();
- if (MA_MEMBER(item, TTextGridView)) {
- dlogDescPtr->has_text = TRUE;
- aCell.v = (short)gridItem->fRow;
- aCell.h = (short)gridItem->fColumn;
- TTextGridViewPtr(gridItem->fGridView)->GetText(aCell, theText);
- MABlockMove((unsigned char*)theText, dlogDescPtr->itemData.text, theText.Length()+1);
- }
- else {
- dlogDescPtr->has_text = FALSE;
- dlogDescPtr->itemData.item_text_ptr = NULL;
- }
- break;
- }
-
- VRectToRect(aVRect, aCRect);
- ::SetRect(&dlogDescPtr->box, aCRect.left,aCRect.top,aCRect.right,aCRect.bottom);
- this->ViewRectToWindowRect (&dlogDescPtr->box, item);
-
- /* fill in ctlRank, owner_rank, and item_num here */
- dlogDescPtr->ctlRank = this->ItemToRank (window, item, FALSE);
- dlogDescPtr->owner_rank = windowRank;
- dlogDescPtr->item_num = itemRank;
-
- /* this ugly thing computes the length (bytes used) of MoleDItemInfo */
- if (itemKind != VINotMember)
- {
- *outputSize = sizeof(MoleDItemInfo) - (255 - dlogDescPtr->itemData.text[0]);
- }
-
- if (gridItem) {
- gridItem->Free();
- }
- }
-
-
- /* ------------------------------------------------------------------------------------ */
- /* routines for searching through the view tree to find particular views */
-
- /* Given the rank (z-order) of a window, return the window object. Invisible
- windows are not considered to be in the window list, for ranking purposes. */
-
- TWindow *TVUAssist::RankToWindow (short rank)
- {
- short i = 1;
- WindowRef window = ::FrontWindow();
-
- while (window) {
- if (IsWindowVisible(window)) {
- if (i == rank) {
- return gApplication->WMgrToWindow(window);
- }
- i = i+1;
- }
- window = GetNextWindow(window);
- }
-
- return NULL;
- }
-
-
- /* Given a window ptr, return the window's rank (z-order) */
-
- short TVUAssist::WindowToRank (WindowRef WindToFind)
- {
- short i = 1;
- WindowRef window = ::FrontWindow();
-
- while (window) {
- if (IsWindowVisible(window)) {
- if (WindToFind == window) {
- return i;
- }
- i = i+1;
- }
- window = GetNextWindow(window);
- }
-
- return 0;
- }
-
-
- /* Convert a point in global coordinates to window coordinates. */
-
- void TVUAssist::GlobalToWindow (TWindow *window, Point Pt, VPoint *VPt)
- {
- VPt->h = 0;
- VPt->v = 0;
-
- GrafPtr savePort;
- ::GetPort(&savePort);
- ::SetPort(window->GetGrafPort());
- if (window->Focus())
- {
- CPoint targetPoint(Pt);
- GlobalToLocal(&targetPoint);
- *VPt = window->QDToViewPt(targetPoint);
- }
- ::SetPort(savePort);
- }
-
-
- /* Convert a point in window coordinates to a subview's coordinates. Return both a
- VPoint and a QDPoint. */
-
- void TVUAssist::WindowToView (TView *view, VPoint *VPt, Point *Pt)
- {
- Pt->h = 0;
- Pt->v = 0;
- view->WindowToLocal(*VPt);
- if (view->Focus()) {
- Pt = view->ViewToQDPt (*VPt);
- }
- }
-
-
- /* In the front (active) window, given the menu ID of a popup item, return the
- popup menu object and its rank. */
-
- static TView *FoundView_MenuIDToPopup = NULL;
- static short MenuID_MenuIDToPopup;
-
- static Boolean TestSubID_MenuIDToPopup(TView *theSubView, TVUAssist *self)
- {
- if (theSubView->IsShown()) {
- if (self->GetItemType(theSubView, FALSE, FALSE) == VIPopup) {
- if (TPopupPtr(theSubView)->fMenuID == MenuID_MenuIDToPopup) {
- FoundView_MenuIDToPopup = theSubView;
- }
- }
- if (FoundView_MenuIDToPopup == NULL) {
- CSubViewIterator iter(theSubView);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubID_MenuIDToPopup(aView, self))
- break;
- }
- }
- }
- return FoundView_MenuIDToPopup != NULL;
- }
-
- TPopup *TVUAssist::MenuIDToPopup (short menuID)
- {
- FoundView_MenuIDToPopup = NULL;
- MenuID_MenuIDToPopup = menuID;
-
- TWindow *window = gApplication->GetActiveWindow(TRUE);
-
- if (window && window->IsShown()) {
- CSubViewIterator iter(window);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubID_MenuIDToPopup(aView, this))
- break;
- }
- }
- return TPopupPtr(FoundView_MenuIDToPopup);
- }
-
-
- /* Given a window object and a point in global coordinates,
- find the control which is under that point. Only descendants of
- TCtlMgr are considered.*/
-
- static TView *FoundView_PointToControl;
- static VPoint VPt_PointToControl;
-
- static Boolean TestSubView_PointToControl(TView *theSubView, TVUAssist *self)
- {
- VPoint testPoint;
- Point dummyPoint;
-
- if (theSubView->IsShown()) {
- if (MA_MEMBER(theSubView, TCtlMgr)) {
- testPoint = VPt_PointToControl;
- self->WindowToView (theSubView, &testPoint, &dummyPoint);
- if (theSubView->ContainsMouse(testPoint)) {
- FoundView_PointToControl = theSubView;
- }
- }
- if (FoundView_PointToControl == NULL) {
- CSubViewIterator iter(theSubView);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_PointToControl(aView, self))
- break;
- }
- }
- }
- return FoundView_PointToControl != NULL;
- }
-
-
- TCtlMgr *TVUAssist::PointToControl (TWindow *window, Point Pt, short *rank)
- {
- FoundView_PointToControl = NULL;
- this->GlobalToWindow (window, Pt, &VPt_PointToControl);
-
- if (window->IsShown()) {
- CSubViewIterator iter(window);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_PointToControl(aView, this))
- break;
- }
- }
-
- *rank = this->ItemToRank (window, FoundView_PointToControl, FALSE);
- return TCtlMgrPtr(FoundView_PointToControl);
- }
-
- static short ItemCount_ViewCount = 0;
-
- static void DoToSubView_ViewCount(TView *theSubView, TVUAssist *self, Boolean dlogViewItems)
- {
- if (theSubView->IsShown()) {
-
- ViewItems ItemType = self->GetItemType (theSubView, dlogViewItems, dlogViewItems);
- if (ItemType != VINotMember) {
- if (ItemType == VIGridItem) {
- ItemCount_ViewCount += self->CountGridItems (TGridViewPtr(theSubView));
- } else {
- ItemCount_ViewCount++;
- }
- }
- if (MA_MEMBER(theSubView, TView)) {
- CSubViewIterator iter(theSubView);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- DoToSubView_ViewCount(aView, self, dlogViewItems);
- }
- }
- }
- }
-
-
- /* Walk the view hierarchy tree, counting the number of user interface items.
- Only visible views and items are counted. */
-
- short TVUAssist::ViewCount (TWindow *window, Boolean dlogViewItems)
- {
- ItemCount_ViewCount = 0;
-
- if (window->IsShown()) {
- CSubViewIterator iter(window);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- DoToSubView_ViewCount(aView, this, dlogViewItems);
- }
- }
- return ItemCount_ViewCount;
- }
-
-
- /* Given a control or dialog item (view), and the window its in (window), return its rank. */
-
- static short ItemCount_ItemToRank;
- static short Rank_ItemToRank;
- static TView *View_ItemToRank;
-
- static Boolean TestSubView_ItemToRank(TView *theSubView, TVUAssist *self, Boolean dlogViewItems)
- {
- if (theSubView->IsShown()) {
-
- ViewItems ItemType = self->GetItemType (theSubView, dlogViewItems, dlogViewItems);
- if (ItemType != VINotMember) {
- if (ItemType == VIGridItem) {
- if (MA_MEMBER(View_ItemToRank, TGridItem) && (theSubView == TGridItemPtr(View_ItemToRank)->fGridView)) {
- Rank_ItemToRank = ItemCount_ItemToRank + (short)(TGridItemPtr(View_ItemToRank)->fRank);
- } else {
- ItemCount_ItemToRank += self->CountGridItems (TGridViewPtr(theSubView));
- }
- } else {
- ItemCount_ItemToRank++;
- if (theSubView == View_ItemToRank) {
- Rank_ItemToRank = ItemCount_ItemToRank;
- }
- }
- }
- if (Rank_ItemToRank == 0) {
- CSubViewIterator iter(theSubView);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_ItemToRank(aView, self, dlogViewItems))
- break;
- }
- }
- }
- return Rank_ItemToRank != 0;
- }
-
-
- short TVUAssist::ItemToRank (TWindow *window, TView *view, Boolean dlogViewItems)
- {
- Rank_ItemToRank = 0;
- ItemCount_ItemToRank = 0;
- View_ItemToRank = view;
-
- if (window->IsShown()) {
- CSubViewIterator iter(window);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_ItemToRank(aView, this, dlogViewItems))
- break;
- }
- }
- return Rank_ItemToRank;
- }
-
-
- static TView *FoundView_RankToItem;
- static short ItemCount_RankToItem;
- static short Rank_RankToItem;
- static Boolean DlogViewItems_RankToItem;
-
- /* Given a window object and the rank (z-order) of an item, return the item object. If
- the item is a cell of a TGridView object, return that object in gridItem.*/
-
- static Boolean TestSubView_RankToItem(TView *theSubView, TVUAssist *self, TGridItem*& gridItem)
- {
- if (theSubView->IsShown()) {
-
- ViewItems ItemType = self->GetItemType (theSubView, DlogViewItems_RankToItem, DlogViewItems_RankToItem);
- if (ItemType != VINotMember) {
- if (ItemType == VIGridItem) {
- short GridCount = self->CountGridItems (TGridViewPtr(theSubView));
- if ((Rank_RankToItem > ItemCount_RankToItem) && (Rank_RankToItem <= ItemCount_RankToItem + GridCount)) {
- gridItem = new TGridItem;
- gridItem->IGridItem(TGridViewPtr(theSubView), Rank_RankToItem - ItemCount_RankToItem);
- FoundView_RankToItem = theSubView;
- }
- ItemCount_RankToItem += GridCount;
- } else {
- ItemCount_RankToItem++;
- if (ItemCount_RankToItem == Rank_RankToItem) {
- FoundView_RankToItem = theSubView;
- }
- }
- }
- if (FoundView_RankToItem == NULL) {
- CSubViewIterator iter(theSubView);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_RankToItem(aView, self, gridItem))
- break;
- }
- }
- }
- return FoundView_RankToItem != NULL;
- }
-
-
- TView *TVUAssist::RankToItem (TWindow *window, short rank, Boolean dlogViewItems, TGridItem*& gridItem)
- {
- FoundView_RankToItem = NULL;
- ItemCount_RankToItem = 0;
- Rank_RankToItem = rank;
- DlogViewItems_RankToItem = dlogViewItems;
-
- if (window->IsShown()) {
- CSubViewIterator iter(window);
- for (TView * aView = iter.FirstSubView(); iter.More(); aView = iter.NextSubView()) {
- if (TestSubView_RankToItem(aView, this, gridItem))
- break;
- }
- }
- return FoundView_RankToItem;
- }
-
-
- /* Report the number of items in a TGridView. This is here so it can
- be easily overridden if you only want rows or columns to show up as
- seperate user interface items, instead of each cell. */
-
- short TVUAssist::CountGridItems (TGridView *theGridView)
- {
- return theGridView->fNumOfRows * theGridView->fNumOfCols;
- }
-
-
- /* Given a view item and the control/dialog item flag, decide if this
- view object is a control if the flag=ControlsOnly, or if its a dialog
- item if the flag=DialogItems, or if its neither. Of course, MacApp
- doesn't have a concept of dialog items, so we improvise. Here are the criteria.
- Any descendent of TCtlMgr is a control. Descendants of TPopup are also classified
- as contols because V.U. can normally only deal with popups which utilize the popup
- CDEF. So V.U. expects popups to be controls.
- Descendents of TTEView and some descendants of TControl (specifically TEditText,
- TStaticText, TIcon, TPicture, and TGridView) are considered to be DialogItems for V.U.'s sake.
- gridViewItems are considered along with other dlogViewItems only if gridViewItems parameter
- is true.*/
-
- ViewItems TVUAssist::GetItemType (TView *item, Boolean dlogViewItems, Boolean gridViewItems)
- {
- if (MA_MEMBER(item, TPopup)) return VIPopup;
- if (MA_MEMBER(item, TRadio)) return VIRadio;
- if (MA_MEMBER(item, TCheckBox)) return VICheckBox;
- if (MA_MEMBER(item, TScrollBar)) return VIScrollBar;
- if (MA_MEMBER(item, TButton)) return VIButton;
-
- if (dlogViewItems) {
- if (MA_MEMBER(item, TEditText)) return VIEditText;
- if (MA_MEMBER(item, TStaticText)) return VIStatText;
- if (MA_MEMBER(item, TIcon)) return VIIcon;
- if (MA_MEMBER(item, TPicture)) return VIPicture;
- if (MA_MEMBER(item, TTEView) && ! MA_MEMBER(item, TDialogTEView))
- return VITextEdit;
- if (fGridItemSupport && gridViewItems) {
- if (MA_MEMBER(item, TGridView))
- return VIGridItem;
- }
- }
-
- return VINotMember;
- }
-
-
- /*========================================== TGridItem ================================*/
-
- #undef Inherited
- #define Inherited TObject
-
- #pragma segment AInit
- MA_DEFINE_CLASS_M1(TGridItem, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TGridItem destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- TGridItem::~TGridItem()
- {
- }
-
- #pragma segment AVUAssist2
-
- /* Instantiate a TGridItem object, and fill in its fields.. This is here
- so it can be overridden if you only want rows or columns to show
- up as seperate user interface items, instead of each individual cells. */
-
- void TGridItem::IGridItem (TGridView *theGridView, short rank)
- {
- this->IObject();
- this->fGridView = theGridView;
- this->fRank = rank;
- this->fRow = (rank - 1) / theGridView->fNumOfCols +1;
- this->fColumn = (rank - 1) % theGridView->fNumOfCols +1;
- }
-
- /* Provide the bounding rect of a griditem */
-
- void TGridItem::GetExtent (VRect& itsExtent)
- {
- GridCell aCell((short)fColumn, (short)fRow);
- fGridView->CellToVRect (aCell, itsExtent);
- }
-
-
- /* call the LocalToWindow method of the GridView associated with the griditem */
-
- void TGridItem::LocalToWindow(VPoint *thePoint)
- {
- fGridView->LocalToWindow(*thePoint);
- }
-
- #endif // of #if qNeedsVU
-
- //----------------------------------------------------------------------------------------
- // End of UVUAssist.cp
-
- #pragma segment Inline
-